package abel.wlmr.model.type;

import abel.util.StdBcdNumber;
import abel.wlmr.model.WlmrBaseUnit;
import abel.wlmr.model.WlmrException;
import io.netty.buffer.ByteBuf;

/**
 * B.5.11.1.3.3 曲线类数据时标Td_c
 * 曲线类数据时标 Td_c 的长度为 7 个字节，由要求终端上传的曲线数据的起始时间 ts、数据冻结密度
 * m 和数据点数 n 组成，表示所请求或响应的曲线数据是从起始时间 ts 起，以冻结密度 m 为间隔的连续 n
 * 个点的曲线数据。数据格式见表 B.118。
 * 表B.118 曲线类数据时标 Td_c 数据格式
 * 数据内容 数据格式 字节数
 * 起始时间 ts：分时日月年 见附录 C.15 5
 * 数据冻结密度 m BIN 1
 * 数据点数 n BIN 1
 * 数据冻结密度 m 定义见附录 E。
 * 
 * @author Abel
 *
 */
public class CurvePointBody extends WlmrBaseUnit {

    public static final short FIXED_LENGTH = 5 + 1 + 1;

    /**
     * 起始时间 ts：分时日月年 见附录 C.15 5
     */
    private StdBcdNumber startTime;

    /**
     * 数据冻结密度 m BIN 1
     * 数据冻结密度 m 定义见附录 E。
     */
    private FrozeDensityType mFroze = FrozeDensityType.M60;

    /**
     * 数据点数 n BIN 1
     */
    private short nPoint;

    /**
     * 
     */
    public CurvePointBody() {
        super();
    }

    /**
     * @param guessedLen
     */
    public CurvePointBody(short guessedLen) {
        super(guessedLen);
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.AppUnitBody#appendBuf(io.netty.buffer.ByteBuf)
     */
    @Override
    public ByteBuf appendBuf(ByteBuf buf) {
        if (startTime == null || startTime.length() != 5) {
            throw new IllegalArgumentException("start time should be 5 bcd number length");
        }

        buf.writeBytes(startTime.toBytes());
        buf.writeByte(mFroze.getValue());
        buf.writeByte(nPoint);

        return buf;
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.AppUnitBody#parseBuf(io.netty.buffer.ByteBuf)
     */
    @Override
    public int parseBuf(ByteBuf buf) throws WlmrException {
        if (checkBuffer(buf) < 0) {
            return -1;
        }

        startTime = new StdBcdNumber();
        startTime.populateBytes(buf, 5);

        mFroze = FrozeDensityType.findEnumByValue(0xFF & buf.readByte());
        nPoint = (short) (0xFF & buf.readByte());

        return getGuessedLength();
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.WlmrDataPart#getMinLength()
     */
    @Override
    public int getMinLength() {
        return FIXED_LENGTH;
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.WlmrDataPart#getFinalLen()
     */
    @Override
    public short getFinalLen() {
        return FIXED_LENGTH;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return String.format("{startTime:%s, mFroze:%s, nPoint:%s}", startTime, mFroze, nPoint);
    }

    /**
     * 起始时间 ts：分时日月年 见附录 C.15 5
     * 
     * @return the startTime
     */
    public StdBcdNumber getStartTime() {
        return startTime;
    }

    /**
     * 起始时间 ts：分时日月年 见附录 C.15 5
     * 
     * @param startTime
     *            the startTime to set
     */
    public void setStartTime(StdBcdNumber startTime) {
        this.startTime = startTime;
    }

    /**
     * 数据冻结密度 m BIN 1
     * 数据冻结密度 m 定义见附录 E。
     * 
     * @return the mFroze
     */
    public FrozeDensityType getmFroze() {
        return mFroze;
    }

    /**
     * 数据冻结密度 m BIN 1
     * 数据冻结密度 m 定义见附录 E。
     * 
     * @param mFroze
     *            the mFroze to set
     */
    public void setmFroze(FrozeDensityType mFroze) {
        this.mFroze = mFroze;
    }

    /**
     * 数据点数 n BIN 1
     * 
     * @return the nPoint
     */
    public short getnPoint() {
        return nPoint;
    }

    /**
     * 数据点数 n BIN 1
     * 
     * @param nPoint
     *            the nPoint to set
     */
    public void setnPoint(short nPoint) {
        this.nPoint = nPoint;
    }

}
